package com.ews.onlineexchange.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import com.ews.onlineexchange.exception.CustomExcepetionHandler;
import com.ews.onlineexchange.exception.ExceptionRedirector;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.model.UploadedFile;

import com.alibaba.fastjson.JSONObject;
import com.ews.onlineexchange.model.Attachment;
import com.ews.onlineexchange.model.Image;

@Named
@ApplicationScoped
public class AttachmentUtils {

	public static final String	SAVE_DIR	= "com.ews.onlineExchange.saveDir";
	
	@Inject
	Config						config;

	/**
	 * 
	 * @param type
	 * @return
	 */
	public String getRelativeDir(AttachmentType type,Date date) {
		Calendar cal = Calendar.getInstance();
		if(date != null)cal.setTime(date);
		String relativePath = "";
		relativePath = relativePath + cal.get(Calendar.YEAR) + "/";
		relativePath = relativePath + (cal.get(Calendar.MONTH) + 1) + "/";
		relativePath = relativePath + type.name().toLowerCase() + "/";
		return relativePath;
	}

	public String getSaveRootDir() {
		return config.getProperty(SAVE_DIR);
	}

	public void saveFileToDisk(String relativeFilename, byte[] data) {
		String savepath = getSaveRootDir() + relativeFilename;
		try {
			FileUtils.writeByteArrayToFile(new File(savepath), data);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public String getFullPath(Attachment attr) {
		if(attr == null) return "";
		Config config = new Config();
		return config.getProperty("com.ews.onlineExchange.uploadContextPath")+"/"+attr.getFilepath();
	}
	
	public Image getImageFromUpload(UploadedFile uploadedFile) {
		Image image = new Image();
		String fileName = uploadedFile.getFileName();
		JSONObject fileInfo = getFileInfo(fileName,AttachmentType.Image, image.getCreateDate());
		String diskFileName = fileInfo.getString("diskFileName");
		String filepath = fileInfo.getString("filepath");
		image.setFilename(fileName);
		image.setFilepath(filepath);
		image.setDiskFileName(diskFileName);
		image.setThumbnailPath(image.getFilepath());
		image.setFilesize(uploadedFile.getSize());
		image.setCreateDate(new Date());
		image.setUpdateDate(new Date());
		saveFileToDisk(filepath, uploadedFile.getContents());
		return image;
	}
	
	public Attachment getAttachmentFromUpload(UploadedFile uploadedFile) {
		Attachment attr = new Attachment();
		String fileName = uploadedFile.getFileName();
		JSONObject fileInfo = getFileInfo(fileName,AttachmentType.Attachment, attr.getCreateDate());
		String diskFileName = fileInfo.getString("diskFileName");
		String filepath = fileInfo.getString("filepath");
		attr.setFilename(fileName);
		attr.setFilepath(filepath);
		attr.setDiskFileName(diskFileName);
		attr.setFilesize(uploadedFile.getSize());
		attr.setCreateDate(new Date());
		attr.setUpdateDate(new Date());
		saveFileToDisk(filepath, uploadedFile.getContents());
		return attr;
	}
	
	public static void main(String[] args) throws ParseException {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		Date date = sf.parse("2019-12-12");
		AttachmentUtils util = new AttachmentUtils();
		System.out.println(util.getRelativeDir(AttachmentType.Attachment, date));
	}
	
	public JSONObject getFileInfo(String fileName,AttachmentType attachmentType,Date fileDate) {
		JSONObject json = new JSONObject();
		String diskFileName = System.currentTimeMillis() + "." + FilenameUtils.getExtension(fileName);
		String relativePath = getRelativeDir(attachmentType,fileDate);
		String filepath = relativePath + diskFileName;
		json.put("diskFileName", diskFileName);
		json.put("filepath", filepath);
		return json;
	}

	public static byte[] getBytes(String filePath){
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(8192);
            byte[] b = new byte[8192];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
			ExceptionRedirector exceptionRedirector = new ExceptionRedirector();
			exceptionRedirector.fileNotFoundExcepetionHandle();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }
	/**
	 * 
	 * @param base64ImageData
	 * @return
	 */
	public Image getPhoto(String base64ImageData) {
		if (StringUtils.isBlank(base64ImageData))
			return null;
		byte[] data = Base64.getDecoder().decode(base64ImageData);
		try {
			String relativeFilename = getRelativeDir(AttachmentType.Image,null) + Calendar.getInstance().getTimeInMillis()
					+ ".jpg";
			String savepath = getSaveRootDir() + relativeFilename;
			FileUtils.writeByteArrayToFile(new File(savepath), data);

			Image image = new Image();
			image.setFilename(relativeFilename.substring(relativeFilename.lastIndexOf("/")));
			image.setDiskFileName(image.getFilename());
			image.setFilepath(relativeFilename);
			image.setFilesize(new File(savepath).getTotalSpace());
			image.setContentType(Files.probeContentType(FileSystems.getDefault().getPath(savepath)));
			image.setThumbnailPath(image.getFilepath());

			return image;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
